package org.springblade.modules.mes.opcua.server;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ReflectUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.tool.utils.ObjectUtil;
import org.springblade.modules.mes.base.entity.*;
import org.springblade.modules.mes.base.service.IStationAssemblyService;
import org.springblade.modules.mes.opcua.constant.OpcUaCache;
import org.springblade.modules.mes.opcua.constant.OpcUaError;
import org.springblade.modules.mes.opcua.constant.OpcUaKey;
import org.springblade.modules.mes.opcua.itf.OpcUa;
import org.springblade.modules.mes.opcua.vo.OpcUaVO;
import org.springblade.modules.mes.quality.entity.AnalysisProcessParam;
import org.springblade.modules.mes.quality.service.IAnalysisProcessParamService;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * 产品生产相关
 */
@Service
@AllArgsConstructor
@Slf4j
public class ParamService {


	private final IStationAssemblyService stationAssemblyService;

	private final IAnalysisProcessParamService analysisProcessParamService;

	private final ToolService toolService;

	/**
	 * 申请总成流水号
	 */
	@DSTransactional
	@DS("master")
	public void saveParam(OpcUaVO ctx) throws Exception {

		//查询站位
		ProduceSite site = OpcUaCache.getBySiteCode(ctx.getSiteCode());
		if (site == null) {
			toolService.plcMessage(ctx, OpcUaError.E01000);
			OpcUa.getInstance().writeValue(ctx, ctx.getPosition(), OpcUaKey.paramStatus, (short) 3);
			return;
		}

		//所有上架订单
		List<StationAssembly> stationAssemblys = stationAssemblyService.list(new QueryWrapper<StationAssembly>().lambda()
			.eq(StationAssembly::getStationCode, site.getStationCode())
			.eq(StationAssembly::getSiteCode, site.getSiteCode())
			.eq(StationAssembly::getPosition, ctx.getPosition())
			.eq(StationAssembly::getStatus, 0));

		if (stationAssemblys == null || stationAssemblys.size() == 0) {
			toolService.plcMessage(ctx, OpcUaError.E31006);
			OpcUa.getInstance().writeValue(ctx, ctx.getPosition(), OpcUaKey.paramStatus, (short) 3);
			return;
		}
		StationAssembly assembly = stationAssemblys.get(0);
		//取得当前上架工序的
		List<PrdBomParam> prdBomParamList = toolService.findBomParaByStation(assembly.getAssemblyNo(), site);
		String position;


		try {
			AnalysisProcessParam analysisProcessParam = new AnalysisProcessParam();
			analysisProcessParam.setAssemblyNo(assembly.getAssemblyNo());
			ProduceStation s = OpcUaCache.getByStationCode(site.getStationCode());
			if (s == null) {
				analysisProcessParam.setStation(site.getStationCode());
			} else {
				analysisProcessParam.setStation(s.getStationName());
			}
			analysisProcessParam.setAssemblyBarcode(assembly.getAssemblyBarcode());
			PrdInfo prd = OpcUaCache.getByProdCode(assembly.getAssemblyNo());
			analysisProcessParam.setType(prd.getMaterialType());
			analysisProcessParam.setProductionLine(prd.getProductionLineCode());
			analysisProcessParam.setDataEndTime(DateUtil.formatTime(new Date()));
			Object temp;
			Float paramValue;
			if (prdBomParamList.size() > 0) {
				for (PrdBomParam bomParam : prdBomParamList) {
					position = bomParam.getParamPosition();
					temp = OpcUa.getInstance().readValue(ctx.opcuaKey(OpcUaKey.param + position, ctx.getPosition()));
					paramValue = Float.valueOf(ObjectUtil.isNotEmpty(temp) ? temp.toString() : "0");
					ReflectUtil.invoke(analysisProcessParam, "setData" + position, String.valueOf(paramValue));
					ReflectUtil.invoke(analysisProcessParam, "setDataName" + position, bomParam.getParamType());
				}
			}

			analysisProcessParamService.save(analysisProcessParam);
			OpcUa.getInstance().writeValue(ctx, ctx.getPosition(), OpcUaKey.paramStatus, (short) 2);
		} catch (Exception ex) {
			ex.printStackTrace();
			toolService.plcMessage(ctx, OpcUaError.E71000);
			OpcUa.getInstance().writeValue(ctx, ctx.getPosition(), OpcUaKey.paramStatus, (short) 3);
		}
	}
}
